import asyncio
import threading


@asyncio.coroutine  # 标明方法是一个coroutine generator
def hi():
    print(threading.current_thread(), 'hello')
    r = yield from asyncio.sleep(1)  # yield调用另一个generator asyncio.sleep()也是一个coroutine
    print(threading.current_thread(), 'world')


def test1():
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.wait([hi(), hi()]))  # hi方法会并行执行，互不影响，并行采用的协程方式执行
    loop.close()


@asyncio.coroutine
def wget(host):
    print('wget %s' % host)
    reader, writer = yield from asyncio.open_connection(host, port=80)
    http_head = 'GET / HTTP/1.0 \r\nHOST: %s\r\n\r\n' % host
    writer.write(http_head.encode())
    yield from writer.drain()
    while True:
        line = yield from reader.readline()
        if line == b'\r\n':  # only read header
            break
        print('%s header: %s' % (host, line.decode()))
    writer.close()


def test2():
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.wait([wget(h) for h in ['www.baidu.com', 'www.sina.com', 'www.163.com']]))  # 协程并行发送请求
    loop.close()


async def shit():
    print('shit')
    await asyncio.sleep(1)
    print('bullshit')


def test3():
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.wait([shit(), shit()]))
    loop.close()


if __name__ == '__main__':
    """
        asyncio 是3.4引入的通过@asyncio.coroutine标记为协程generator, asyncio可以实现单线程并发IO操作
        3.5开始提供了新语法async await, 更简洁一些 只需将@asyncio.coroutine替换为 async def funxxx, yield from 替换为 await
    """
    # test1()
    # test2()
    test3()
